﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace UBCon.Navigation
{
    public class DropDownMenu : Menu
    {
        #region Constructors

        #endregion

        #region Properties
        
        [Bindable(true), 
        ReadOnly(false), 
        Browsable(false)]
        public bool IsDropDownOpen
        {
            get { return (bool)GetValue(IsDropDownOpenProperty); }
            set { SetValue(IsDropDownOpenProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsDropDownOpen.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsDropDownOpenProperty =
            DependencyProperty.Register("IsDropDownOpen", typeof(bool), typeof(DropDownMenu),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal));


        [Bindable(true),
       Category("Behavior")]
        public ClickMode ClickMode
        {
            get { return (ClickMode)GetValue(ClickModeProperty); }
            set { SetValue(ClickModeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ClickMode.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ClickModeProperty =
            DependencyProperty.Register("ClickMode", typeof(ClickMode),
            typeof(DropDownMenu),
            new FrameworkPropertyMetadata(ClickMode.Release),
            new ValidateValueCallback(IsValidClickMode));

        [Bindable(true),
        ReadOnly(false)]
        public PlacementMode DropDownPlacement
        {
            get { return (PlacementMode)GetValue(DropDownPlacementProperty); }
            set { SetValue(DropDownPlacementProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DropDownPlacement.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DropDownPlacementProperty =
            DependencyProperty.Register("DropDownPlacement", typeof(PlacementMode), typeof(DropDownMenu), new FrameworkPropertyMetadata(PlacementMode.Top));

        [Bindable(true),
        ReadOnly(false),
        Browsable(false)]
        public UIElement PlacementTarget
        {
            get { return (UIElement)GetValue(PlacementTargetProperty); }
            set { SetValue(PlacementTargetProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PlacementTarget.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PlacementTargetProperty =
            DependencyProperty.Register("PlacementTarget", typeof(UIElement), typeof(DropDownMenu), new FrameworkPropertyMetadata((UIElement)null));


        [Bindable(true),
        ReadOnly(false),
        Browsable(true),
        Category("Appearance")]
        public double MaxDropDownHeight
        {
            get { return (double)GetValue(MaxDropDownHeightProperty); }
            set { SetValue(MaxDropDownHeightProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MaxDropDownHeight.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MaxDropDownHeightProperty =
            DependencyProperty.Register("MaxDropDownHeight", typeof(double), typeof(DropDownMenu),
            new FrameworkPropertyMetadata(SystemParameters.PrimaryScreenHeight * 0.65));

        [Bindable(true),
        ReadOnly(false),
        Browsable(true), Category("Appearance")]
        public bool UserCanResizeDropDown
        {
            get { return (bool)GetValue(UserCanResizeDropDownProperty); }
            set { SetValue(UserCanResizeDropDownProperty, value); }
        }

        // Using a DependencyProperty as the backing store for UserCanResizeDropDown.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty UserCanResizeDropDownProperty =
            DependencyProperty.Register("UserCanResizeDropDown", typeof(bool), typeof(DropDownMenu), new FrameworkPropertyMetadata(false));

        public double DropDownHeight
        {
            get { return (double)GetValue(DropDownHeightProperty); }
            set { SetValue(DropDownHeightProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DropDownHeight.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DropDownHeightProperty =
            DependencyProperty.Register("DropDownHeight", typeof(double), typeof(DropDownMenu), new PropertyMetadata(double.NaN));
        #endregion

        #region Depenency Property Changed Callbacks

        private static bool IsValidClickMode(object value)
        {
            ClickMode clickMode = (ClickMode)value;
            return clickMode == ClickMode.Press
                || clickMode == ClickMode.Release
                || clickMode == ClickMode.Hover;
        }

        public double MinDropDownWidth
        {
            get { return (double)GetValue(MinDropDownWidthProperty); }
            set { SetValue(MinDropDownWidthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MinDropDownWidth.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MinDropDownWidthProperty =
            DependencyProperty.Register("MinDropDownWidth", typeof(double), typeof(DropDownMenu), new FrameworkPropertyMetadata(300.0D));

        #endregion

        #region Overrides

        protected override void OnLostMouseCapture(MouseEventArgs e)
        {
            base.OnLostMouseCapture(e);
            
            if (Mouse.Captured == null) 
            {
                SetIsDropDownOpenValue(false);
            }
        }
        #endregion

        #region Private Utilities

        private void SetIsDropDownOpenValue(bool value) 
        {
            SetValue(IsDropDownOpenProperty, value);
        }
        #endregion

        #region Event Handlers
        #endregion

        #region Fields
        #endregion

        #region Events
        #endregion
    }
}
